home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / HippoDraw / hippo / hippoplotXIV.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-28  |  13.5 KB  |  643 lines

  1. //                              -*- Mode: C++ -*- 
  2. // hippoplotXIV.cc -- Graphics code for producing X/InterViews displays.
  3. //
  4. // Copyright (C)  1991  The Board of Trustees of The Leland Stanford
  5. // Junior University.  All Rights Reserved.
  6. //
  7. // $Header: /nfs/ebnextk/LocalSources/hippo/RCS/hippoplotXIV.cc,v 1.3 1992/01/07 02:51:08 pavel Rel $
  8. //
  9. // Author          : Tom Pavel
  10. // Created On      : Thu Jun  6 09:15:29 1991
  11. // Last Modified By: Tom Pavel
  12. // Last Modified On: Mon Jan  6 16:01:40 1992
  13. // Update Count    : 22
  14. // Status          : Revision 1
  15. // 
  16.  
  17.  
  18. /*
  19.  * Provides the equivalent of:
  20.  * hippowraps.psw - histogramming package postscript wraps. 
  21.  *      by william shipley, at SLAC, august 1990
  22.  *    
  23.  *      modified/maintained by mike gravina.
  24.  *
  25.  * updated to match new psw - Apr 13, 1991 pavel
  26.  *
  27.  * brought into the new mult-driver scheme - Jun 6, 1991 pavel
  28.  *
  29.  * new and improved mult-driver scheme - Sep 22, 1991 pavel
  30.  *
  31.  * minor improvements for release - 3-Jan-1992 pavel 
  32.  *
  33.  */
  34.  
  35.  
  36. #include "hippoplotXIV.h"
  37.  
  38. #include <stdio.h>
  39. #include <string.h>
  40. #include <math.h>
  41. #include <InterViews/canvas.h>
  42. #include <InterViews/painter.h>
  43. #include <InterViews/font.h>
  44. #include <InterViews/color.h>
  45. #include <InterViews/brush.h>
  46. #include <InterViews/raster.h>
  47. #include <InterViews/transformer.h>
  48.  
  49.  
  50. // These are for passing info from Histo class:
  51. Painter* h_plotter;
  52. Canvas*  h_canvas;
  53.  
  54. // All scaling info:
  55. static struct {
  56.    float x;
  57.    float y;
  58.    Coord xMarg;
  59.    Coord yMarg;
  60.    float xOrig;
  61.    float yOrig;
  62. } Scale;
  63.  
  64. // The Data-coords limits:
  65. static struct {
  66.    float xmin;
  67.    float xmax;
  68.    float ymin;
  69.    float ymax;
  70. } Limit;
  71.  
  72.  
  73. inline Coord XScale (float x)
  74. { return Coord((x-Scale.xOrig)*Scale.x)+Scale.xMarg;}
  75.  
  76. inline Coord YScale (float y)
  77. { return Coord((y-Scale.yOrig)*Scale.y)+Scale.yMarg;}
  78.  
  79.  
  80. inline Coord Convert (float d)
  81. // Use the InterViews global var "point" to scale properly for screen
  82. // resolution:
  83. { return Coord(d*point);}
  84.  
  85.  
  86. // Return a Color* corresponding to x.  x is between 0 and 1
  87. static Color* getGrey(float x)
  88. {
  89.    const int max = 65535;    // = 0xffff
  90.    const int fuzz = 0xff;
  91.    int grey = int(x*max) & ~fuzz;
  92.    return (new Color(grey,grey,grey));
  93. }
  94.  
  95. static Color* getInvGrey(float x)
  96. {
  97.    return getGrey(1-x);
  98. }
  99.  
  100. static Color* getColor(float x)
  101. {
  102.    // Well, ok this doesn't quite work; but it produces an interesting effect
  103.    // anyway.  Just goes to show how arbitrary color renderings are....
  104.  
  105.    const int max = 0xffffff;
  106.    int rgb = int(x*max);
  107.    int red = (rgb & 0xff0000) >> 8;
  108.    int green = (rgb & 0x00ff00);
  109.    int blue = (rgb & 0x0000ff) << 8;
  110.    return (new Color(red,green,blue));
  111. }
  112.  
  113.  
  114.  
  115.  
  116. void initPlot_XIV(void* painter, void* canvas)
  117. {
  118.    h_plotter = (Painter*) painter;
  119.    h_canvas  = (Canvas*) canvas;
  120. }
  121.  
  122.  
  123. void setHistoCoords_XIV(rectangle* margin, rectangle* data)
  124. {
  125.    // Get windWidth and windHeight from the HistoView object; Don't
  126.    // listen to what h_plot() tells us!  [Unless, of course, the window
  127.    // is unmapped, and we can't tell anyway]:
  128.  
  129.    if (h_canvas == 0) {
  130.       fprintf(stderr, "setHistoCoords_XIV:  Undefined Canvas\n");
  131.       // return -1;
  132.       return;
  133.    }
  134.    
  135.    
  136.    // Get overall width and height from h_canvas.  Ignore drawRect.
  137.    Coord windWidth  = h_canvas->Width();
  138.    Coord windHeight = h_canvas->Height();
  139.    
  140.    // Remember margin is in points; data is in data coords.
  141.    Scale.x = Convert(margin->size.width)/(data->size.width);
  142.    Scale.y = Convert(margin->size.height)/(data->size.height);
  143.    Scale.xMarg = Convert(margin->origin.x);
  144.    Scale.yMarg = Convert(margin->origin.y);
  145.    Scale.xOrig = data->origin.x;
  146.    Scale.yOrig = data->origin.y;
  147.    
  148.    Limit.xmin = data->origin.x;
  149.    Limit.xmax = data->size.width + data->origin.x;
  150.    Limit.ymin = data->origin.y;
  151.    Limit.ymax = data->size.height + data->origin.y;
  152.    
  153. #ifdef DEBUG
  154.    printf ("setupXIV: X scale = %f, Y scale = %f\n", Scale.x, Scale.y);
  155. #endif
  156. }
  157.  
  158.  
  159.  
  160. // Put the message text at the indicated x-y position (Note, x and y
  161. // are in points):
  162.  
  163. void drawText_XIV(char *message,
  164.           float x,
  165.           float y,
  166.           float fontHeight,
  167.           float angle,
  168.           char xalign,
  169.           char yalign)
  170. {
  171.    // label->SetFont()  <something with fontSize = fontHeight>
  172.    
  173.    int fw = h_plotter->GetFont()->Width(message);
  174.    int fh = h_plotter->GetFont()->Height();
  175.    
  176.    float radangle = angle*M_PI/180.0;
  177.    
  178.    x = Convert(x);
  179.    y = Convert(y);
  180.    
  181.    switch (xalign) {
  182.    case 'C':
  183.    case 'c':
  184.       x -= fw/2*cos(radangle);
  185.       y -= fw/2*sin(radangle);
  186.       break;
  187.       
  188.    case 'R':
  189.    case 'r':
  190.       x -= fw*cos(radangle);
  191.       y -= fw*sin(radangle);
  192.       break;
  193.       
  194.    case 'L':
  195.    case 'l':
  196.    default:
  197.       break;
  198.    }
  199.    
  200.    switch (yalign) {
  201.    case 'C':
  202.    case 'c':
  203.       x += fh/2*sin(radangle);
  204.       y -= fh/2*cos(radangle);
  205.       break;
  206.       
  207.    case 'T':
  208.    case 't':
  209.       x += fh*sin(radangle);
  210.       y -= fh*cos(radangle);
  211.       break;
  212.       
  213.    case 'B':
  214.    case 'b':
  215.    default:
  216.       break;
  217.    }
  218.    
  219.    // Now write text in bg-fill-off mode (adding only the letters)
  220.    boolean fill = h_plotter->BgFilled();
  221.    h_plotter->FillBg(false);
  222.    
  223.    if (angle == 0 ) {
  224.       // Get away with simple text:
  225.       h_plotter->Text(h_canvas, message, Coord(x), Coord(y));
  226.    } else {
  227.       // Have to do some work:
  228.       Transformer* t = new Transformer(h_plotter->GetTransformer());
  229.       
  230.       h_plotter->Rotate(angle);
  231.       h_plotter->Translate(Coord(x),Coord(y));
  232.       
  233.       h_plotter->Text(h_canvas, message, 0, 0);
  234.       
  235.       h_plotter->SetTransformer(t); // restore old transform matrix.
  236.    }
  237.    h_plotter->FillBg(fill);
  238. }
  239.  
  240.  
  241.  
  242. void drawMag_XIV(float x, float y,
  243.          int mag, float fontsize)
  244.  
  245. // x and y are in device coords (points).
  246. {
  247.    // fontsize ignored for now...
  248.    char string[10];
  249.  
  250.    Coord fw = h_plotter->GetFont()->Width("x10");
  251.    Coord fh = h_plotter->GetFont()->Height();
  252.  
  253.    h_plotter->Text(h_canvas, "x10", Convert(x), Convert(y));
  254.  
  255.    h_plotter->Text(h_canvas, sprintf(string,"%d",mag),
  256.            Convert(x)+fw, Convert(y)+fh/2);
  257. }
  258.  
  259.  
  260.  
  261. void drawXTicks_XIV(float* x,
  262.             int nt,
  263.             float tickwidth,
  264.             int side)
  265.  
  266. {
  267.    Coord yBorder;
  268.    Coord width;
  269.    if (side == 0) {
  270.       yBorder = YScale(Limit.ymin);
  271.       width = Convert(tickwidth);
  272.    } else {
  273.       yBorder = YScale(Limit.ymax);
  274.       width = -1*Convert(tickwidth);
  275.    }
  276.  
  277.    while (nt > 0) {
  278.       h_plotter->Line(h_canvas,
  279.               XScale(*x), yBorder,
  280.               XScale(*x), yBorder+width);
  281. #ifdef DEBUG
  282.       printf ("drawXTicks_XIV: tick %f at %d\n", *x, XScale(*x));
  283. #endif
  284.  
  285.       x++;
  286.       nt--;
  287.    }
  288. }
  289.  
  290.  
  291.  
  292. void drawYTicks_XIV(float* y,
  293.             int nt,
  294.             float tickwidth,
  295.             int side)
  296.  
  297. {
  298.    Coord xBorder;
  299.    Coord width;
  300.    if (side == 0) {
  301.       xBorder = XScale(Limit.xmin);
  302.       width = Convert(tickwidth);
  303.    } else {
  304.       xBorder = XScale(Limit.xmax);
  305.       width = -1*Convert(tickwidth);
  306.    }
  307.  
  308.    while (nt > 0) {
  309.       h_plotter->Line(h_canvas,
  310.               xBorder, YScale(*y),
  311.               xBorder+width, YScale(*y));
  312. #ifdef DEBUG
  313.       printf ("drawYTicks_XIV: tick %f at %d\n", *y, YScale(*y));
  314. #endif
  315.  
  316.       y++;
  317.       nt--;
  318.    }
  319. }
  320.  
  321.  
  322.  
  323. void drawRect_XIV(float x, float y,
  324.           float width, float height)
  325.  
  326. // all args are in window coords
  327. {
  328.  
  329.       h_plotter->Rect(h_canvas,
  330.               Convert(x), Convert(y),
  331.               Convert(x+width),Convert(y+height));
  332. #ifdef DEBUG
  333.    printf("drawRect_XIV: rect at (%d, %d) to (%d, %d)\n",
  334.       Convert(x), Convert(y), Convert(x+width),Convert(y+height));
  335. #endif
  336. }
  337.  
  338.  
  339.  
  340. void drawFilledRect_XIV(float x, float y,
  341.             float width, float height,
  342.             float grey)
  343.  
  344. // all args are in window coords
  345. {
  346.    Color* bg = h_plotter->GetBgColor();
  347.    Color* fg = h_plotter->GetFgColor();
  348.    Color* shade = getGrey(grey);
  349.    h_plotter->SetColors(fg, shade);
  350.  
  351.    h_plotter->FillRect(h_canvas,
  352.                Convert(x), Convert(y),
  353.                Convert(x+width),Convert(y+height));
  354.  
  355.    h_plotter->SetColors(fg, bg);
  356.  
  357. #ifdef DEBUG
  358.    printf("drawFilledRect_XIV: rect at (%d, %d) to (%d, %d)\n",
  359.       Convert(x), Convert(y), Convert(x+width),Convert(y+height));
  360. #endif
  361. }
  362.  
  363.  
  364.  
  365. void shade_XIV(float xlow, float xhigh,
  366.                float ylow, float yhigh )
  367.  
  368. // all args are in data coords
  369. {
  370.    const float grey = 0.6;
  371.  
  372.    Color* bg = h_plotter->GetBgColor();
  373.    Color* fg = h_plotter->GetFgColor();
  374.    Color* shade = getGrey(grey);
  375.    h_plotter->SetColors(fg, shade);
  376.  
  377.    h_plotter->FillRect(h_canvas,
  378.                XScale(xlow),  YScale(ylow),
  379.                XScale(xhigh), YScale(yhigh));
  380.  
  381.    h_plotter->SetColors(fg, bg);
  382.  
  383. #ifdef DEBUG
  384.    printf("drawFilledRect_XIV: rect at (%d, %d) to (%d, %d)\n",
  385.       XScale(xlow), YScale(ylow), XScale(xhigh),YScale(yhigh));
  386. #endif
  387. }
  388.  
  389.  
  390.  
  391.  
  392. void drawLine_XIV(float *xy, int nxy, linestyle_t ls)
  393. {
  394.    Coord* x = new Coord[nxy];
  395.    Coord* y = new Coord[nxy];
  396.    
  397.    Coord* xp = x;
  398.    Coord* yp = y;
  399.    for (int i=0; i < nxy; i++) {
  400.       *xp++ = XScale(*xy++);
  401.       *yp++ = YScale(*xy++);
  402.    }
  403.  
  404.    Brush* oldbrush = h_plotter->GetBrush();
  405.    Brush* newbrush;
  406.    
  407.    switch (ls) {
  408.    case SOLID:
  409.    default:
  410.       newbrush = new Brush(0xffff);
  411.       break;
  412.    case DASH:
  413.       newbrush = new Brush(0x0f0f);
  414.       break;
  415.    case DOT:
  416.       newbrush = new Brush(0x3333);
  417.       break;
  418.    case DOTDASH:
  419.       newbrush = new Brush(0xf99f);
  420.       break;
  421.    }
  422.  
  423.    h_plotter->SetBrush(newbrush);
  424.    h_plotter->Clip(h_canvas,
  425.            XScale(Limit.xmin),YScale(Limit.ymin),
  426.            XScale(Limit.xmax),YScale(Limit.ymax));
  427.  
  428.    h_plotter->MultiLine(h_canvas, x, y, nxy);
  429.  
  430.    h_plotter->SetBrush(oldbrush);      // This will Unref() the newbrush.
  431.    h_plotter->NoClip();
  432.    
  433.    delete x;
  434.    delete y;
  435. }
  436.  
  437.  
  438.  
  439.  
  440. void drawPoints_XIV(float xy[],
  441.             int nxy,
  442.             int symbol,
  443.             float symbolsize)
  444. {
  445.  
  446.    h_plotter->Clip(h_canvas,
  447.            XScale(Limit.xmin),YScale(Limit.ymin),
  448.            XScale(Limit.xmax),YScale(Limit.ymax));
  449.  
  450.    Coord ptsize = Convert(symbolsize);
  451.  
  452.    switch (symbol) {
  453.    case SQUARE:
  454.    default:
  455.       while (nxy > 0) {
  456.      h_plotter->Rect(h_canvas,
  457.              XScale(*xy)-ptsize/2, YScale(*(xy+1))-ptsize/2,
  458.              XScale(*xy)+ptsize/2, YScale(*(xy+1))+ptsize/2);
  459.      xy += 2;
  460.      nxy--;
  461.       }
  462.       break;
  463.  
  464.    case SOLIDSQUARE:
  465.       while (nxy > 0) {
  466.      h_plotter->FillRect(h_canvas,
  467.                  XScale(*xy)-ptsize/2, YScale(*(xy+1))-ptsize/2,
  468.                  XScale(*xy)+ptsize/2, YScale(*(xy+1))+ptsize/2);
  469.      xy += 2;
  470.      nxy--;
  471.       }
  472.       break;
  473.  
  474.    case PLUS:
  475.      while (nxy > 0) {
  476.      h_plotter->Line(h_canvas,
  477.              XScale(*xy), YScale(*(xy+1))-ptsize/2,
  478.              XScale(*xy), YScale(*(xy+1))+ptsize/2);
  479.      h_plotter->Line(h_canvas,
  480.              XScale(*xy)-ptsize/2, YScale(*(xy+1)),
  481.              XScale(*xy)+ptsize/2, YScale(*(xy+1)));
  482.      xy += 2;
  483.      nxy--;
  484.       }
  485.       break;
  486.  
  487.    case TIMES:
  488.      while (nxy > 0) {
  489.      h_plotter->Line(h_canvas,
  490.              XScale(*xy)-ptsize/2, YScale(*(xy+1))-ptsize/2,
  491.              XScale(*xy)+ptsize/2, YScale(*(xy+1))+ptsize/2);
  492.      h_plotter->Line(h_canvas,
  493.              XScale(*xy)-ptsize/2, YScale(*(xy+1))+ptsize/2,
  494.              XScale(*xy)+ptsize/2, YScale(*(xy+1))-ptsize/2);
  495.      xy += 2;
  496.      nxy--;
  497.       }
  498.       break;
  499.    }
  500.  
  501.    h_plotter->NoClip();
  502. }
  503.  
  504.  
  505.  
  506.  
  507. void drawXError_XIV(float xy[],
  508.             float errs[],
  509.             int npts)
  510. {
  511.    h_plotter->Clip(h_canvas,
  512.            XScale(Limit.xmin),YScale(Limit.ymin),
  513.            XScale(Limit.xmax),YScale(Limit.ymax));
  514.  
  515.    const Coord HALFERRWIDTH = 5;
  516.    float y = 0;
  517.    float xlo = 0;
  518.    float xhi = 0;
  519.    
  520.    while (npts > 0) {
  521.       xy++;            // ignore x value
  522.       y = *xy++;
  523.       xhi = *errs++;
  524.       xlo = *errs++;
  525.  
  526.       h_plotter->Line(h_canvas,
  527.               XScale(xlo), YScale(y),
  528.               XScale(xhi), YScale(y));
  529.  
  530.       h_plotter->Line(h_canvas,
  531.               XScale(xlo), YScale(y-HALFERRWIDTH),
  532.               XScale(xlo), YScale(y+HALFERRWIDTH));
  533.  
  534.       h_plotter->Line(h_canvas,
  535.               XScale(xhi), YScale(y-HALFERRWIDTH),
  536.               XScale(xhi), YScale(y+HALFERRWIDTH));
  537.  
  538.       npts--;
  539.    }
  540.  
  541.  
  542.    h_plotter->NoClip();
  543. }
  544.  
  545.  
  546. void drawYError_XIV(float xy[],
  547.             float errs[],
  548.             int npts)
  549. {
  550.    h_plotter->Clip(h_canvas,
  551.            XScale(Limit.xmin),YScale(Limit.ymin),
  552.            XScale(Limit.xmax),YScale(Limit.ymax));
  553.  
  554.    const Coord HALFERRWIDTH = 5;
  555.    float x = 0;
  556.    float ylo = 0;
  557.    float yhi = 0;
  558.    
  559.    while (npts > 0) {
  560.       x = *xy;
  561.       xy += 2;
  562.       yhi = *errs++;
  563.       ylo = *errs++;
  564.  
  565.       h_plotter->Line(h_canvas,
  566.               XScale(x), YScale(ylo),
  567.               XScale(x), YScale(yhi));
  568.  
  569.       h_plotter->Line(h_canvas,
  570.               XScale(x-HALFERRWIDTH), YScale(ylo),
  571.               XScale(x+HALFERRWIDTH), YScale(ylo));
  572.  
  573.       h_plotter->Line(h_canvas,
  574.               XScale(x-HALFERRWIDTH), YScale(yhi),
  575.               XScale(x+HALFERRWIDTH), YScale(yhi));
  576.  
  577.       npts--;
  578.    }
  579.  
  580.  
  581.    h_plotter->NoClip();
  582. }
  583.  
  584.  
  585.  
  586. void drawColor2D_XIV(int nXBins,
  587.              int nYBins,
  588.              float minBin,
  589.              float maxBin,
  590.              float bins[])
  591. {
  592.    const float xBinWidth = (Limit.xmax - Limit.xmin)/nXBins;
  593.    const float yBinWidth = (Limit.ymax - Limit.ymin)/nYBins;
  594.    float x = Limit.xmin;
  595.    float y = Limit.ymin;
  596.    const float scale = 1.0 / (maxBin - minBin);
  597.  
  598.    Color* bg = h_plotter->GetBgColor();
  599.    Color* fg = h_plotter->GetFgColor();
  600.    Color* shade;
  601.  
  602.    h_plotter->Clip(h_canvas,
  603.            XScale(Limit.xmin),YScale(Limit.ymin),
  604.            XScale(Limit.xmax),YScale(Limit.ymax));
  605.  
  606.    for (int i=0; i<nXBins; i++) {
  607.       for (int j=0; j<nYBins; j++) {
  608.      shade = getInvGrey(scale * (*bins++ - minBin));
  609.      h_plotter->SetColors(shade, shade);
  610.      h_plotter->FillRect(h_canvas,
  611.                  XScale(x), YScale(y),
  612.                  XScale(x+xBinWidth), YScale(y+yBinWidth));
  613.  
  614.      y += yBinWidth;
  615.       }
  616.       x += xBinWidth;
  617.       y = Limit.ymin;
  618.    }
  619.  
  620.    h_plotter->SetColors(fg, bg);
  621.    h_plotter->NoClip();
  622. }
  623.  
  624.  
  625.  
  626.  
  627. void drawLego2D_XIV(int nXBins,
  628.            int nYBins,
  629.            float minBin,
  630.            float maxBin,
  631.            float bins[])
  632. {
  633.    drawText_XIV("Not implemented yet.",
  634.         XScale((Limit.xmin+Limit.xmax)/2),
  635.         YScale((Limit.ymin+Limit.ymax)/2),
  636.         h_plotter->GetFont()->Height(),
  637.         0,'c','c');
  638.         
  639. }
  640.  
  641.  
  642.  
  643.